;
;   Programming Language: AutoIt v3
;   Load file and draw modules and text
;   Author:
;       ChungChe Hsieh 2011/09/07 (first version)
;       Copyleft, all rights reserved
;   History & Changelog:
;       2011/11/05  1. Add ListView/ListViewItems
;                   2. Load from open file dialog
;                   3. Create a new window, one for showing modules, one for listing
;                   4. List support Name/Position/Width/Height/Area (Single select and enable title droppable)
;       2011/11/06  1. Use GDIP to draw module, the old version using create_button to create module buttons
;                   2. Window size created by aspect ratio
;       2011/11/09  1. Change fill rect to draw rectangle
;                   2. Draw font to the middle of block
;                   3. Change xres, yres to 750, up from 600
;                   4. Bug Fix: when sorted by column, should get index from first column, not index
;                   5. Add gFontSize as global variable @Q@
;       2011/11/11  1. Load sol file from comboBox
;                   2. Add .myPath config file
;       2011/11/14  1. Draw top-right line
;
#include <GuiConstantsEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <File.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiButton.au3>
#include <Color.au3>
#include <GDIP.au3>
#include <GuiEdit.au3>
#include <ScrollBarConstants.au3>
#include <GuiListView.au3>
#include <_ArraySize.au3>
Opt( "MustDeclareVars", 1 );
Opt( "GuiOnEventMode",  1 );
; ===================================================
; Global vars
Global $verbose         = 1
Global $lastClick       = -1
Global $xres            = 750
Global $yres            = 750
Global $maxX            = -9999999
Global $maxY            = -9999999
Global $minX            =  9999999
Global $minY            =  9999999
Global $totModules      = 0
Global $gFontSize       = 10
Global $FileList        = 0
Global $ModulePath      = 0
; ====== GDIP relative variables ======
Global $graphic         = 0
Global $bitmap          = 0
Global $buffer          = 0
; Array size will be size + 1, the first element is null since
; it cannot support zero size array :(
Global $modNameAry[1];
Global $modX1Ary[1], $modY1Ary[1], $modX2Ary[1], $modY2Ary[1]
Global $modWidth[1], $modHeight[1];
Global $modP1XAry[1], $modP1YAry[1];
Global $modP2XAry[1], $modP2YAry[1];
;Global $butAry[1]
Global $itemAry[1]
; Widgets
Global $GUImodWindow    = 0;
Global $GUImodList      = 0;
Global $EDIT            = 0;
Global $but_OK         = 0;
Global $but_SP         = 0;
Global $listView        = 0;
Global $comboBox        = 0;
; ===================================================
;Func create_input($obj,$val, $str, $pos_x, $pos_y,$callback)
;    GuiCtrlCreateLabel($str, $pos_x, $pos_y+3)
;    $obj = GuiCtrlCreateInput(($val), $pos_x+70, $pos_y, 70, 20)
;    GuiCtrlSetOnEvent(-1, String($callback))
;    GuiCtrlCreateUpDown(-1)
;    return $obj
;EndFunc
; ===================================================
Func create_button( $str, $pos_x, $pos_y, $width, $height,$callback)
    Local $var
    $var = GuiCtrlCreateButton($str, $pos_x, $pos_y, $width, $height)
    ;_GuiCtrlMakeTrans(-1,100); 
    ;msgbox(0,"lol","ok");
    GuiCtrlSetOnEvent(-1, $callback)
    return $var
Endfunc
; ===================================================
Func create_listView( $obj, $pos_x, $pos_y, $width, $height, $callback )
    if $obj <> 0 then
        GuiCtrlDelete( $obj )
    endif 
    $obj = GUICtrlCreateListView( "Idx|Module Name| Left |Bottom| Right  |Top |Width |Height |Area", $pos_x, $pos_y, $width, $height, $LVS_SINGLESEL, BitOR($LVS_EX_HEADERDRAGDROP,$LVS_EX_FULLROWSELECT) );
    ;$obj = GUICtrlCreateListView("Idx|Module Name| Left |Bottom| Top  |Right |Width |Height |Area", $pos_x, $pos_y, $width, $height, $LVS_SINGLESEL );
    ;msgbox(0,"lol",stringformat("obj=%d",$obj))
    GuiCtrlSetOnEvent( -1, $callback )
    return $obj
EndFunc
; ===================================================
Func create_listViewItem( $obj, $idx, $moduleName, $pos_x1, $pos_y1, $pos_x2, $pos_y2, $width, $height, $callback )
    Local $item
    ;msgbox(0,"lol", stringformat("%s|%s|%s|%s|%s",$moduleName,$pos_x1,$pos_y1,$pos_x2,$pos_y2) );
    $item = GUICtrlCreateListViewItem( stringformat("%d|%s|%s|%s|%s|%s|%s|%s|%d",$idx, $moduleName,$pos_x1,$pos_y1,$pos_x2,$pos_y2,$width,$height,int($width)*int($height)), $obj ); 
        ;msgbox(0, "lol", stringformat("%d %d %d %d",NormalizeX(int($strs[2])), NormalizeY(int($strs[3])), NormalizeX(int($strs[4])),NormalizeY(int($strs[5]))))
    ;msgbox(0,"lol",stringformat("obj=%d item=%d",$obj,$item))
    GUICtrlSetOnEvent( -1, $callback );
    return $item
EndFunc
; ===================================================
Func print( $str )
    if $verbose == 1 then
        ;_GuiCtrlEdit_AppendText($EDIT,$str & @CRLF)
    endif
EndFunc
; ==================================================
Func listView_clicked()
    _GUICtrlListView_RegisterSortCallBack($listView)
    _GUICtrlListView_SortItems($listView, GUICtrlGetState($listView));
    _GUICtrlListView_UnRegisterSortCallBack($listView)
EndFunc
; ==================================================
Func create_combo( $gpName,$x,$y,$w,$h,$callback )
    Local $combo
	GuiCtrlCreateGroup($gpNAme, $x, $y, $w, $h)
	; COMBO
	$combo = GuiCtrlCreatecombo( "", $x+15, $y+15, $w-30, 100 )
	GUICtrlSetOnEvent( -1, $callback )
	GUICtrlCreateGroup ("",-99,-99,1,1 )  ;close group
    return $combo
EndFunc
; ===================================================
Func button_clickedSP()
    ; get edit line by line
    SPCallback()
EndFunc
; ===================================================
Func button_clicked()
    ; get edit line by line
    comboBoxCallback()
EndFunc
; ===================================================
; ===================================================
; Create GUI window for listing all modules
; ===================================================
Func create_ListWindow()
    ;if $GUImodWindow <> 0 then
    ;    GUIDelete($GUImodList)
    ;endif
    $GUImodList = GuiCreate(stringformat("Module Lists"), 600, 700, 20, 100, -1, $WS_EX_ACCEPTFILES)
    GUISetOnEvent($GUI_EVENT_CLOSE, "GUI_close");
    ;$comboBox = create_combo( "Select a solution file", 20, 20, 550, 50, "comboBoxCallback" )
    $EDIT = GuiCtrlCreateEdit("", 20, 80, 450, 150, BitOR($ES_WANTRETURN, $WS_VSCROLL))
    $listView = create_listView($listView, 20, 250, 550, 400, "listView_clicked"); 
    ;SetComboBox($comboBox, $FileList)
    $but_OK = create_button( "Draw", 20, 20, 60, 40, "button_clicked")
    $but_SP = create_button( "Draw SP", 100, 20, 60, 40, "button_clickedSP")
    GuiSetState()
EndFunc
; ===================================================
; Create GUI window for showing modules
; ===================================================
Func create_window()
    if $GUImodWindow <> 0 then
        GUIDelete($GUImodWindow)
    endif
    $GUImodWindow = GuiCreate(stringformat("Show Modules"), $xres, $yres, -1, -1, -1, $WS_EX_ACCEPTFILES)
    GUISetOnEvent($GUI_EVENT_CLOSE, "GUI_close");
    ;GUIRegisterMsg(0x00f, "PAINT_FLUSH") 

    ;PAINT_FLUSH()
    ;$listView = create_listView($listView, 300, 20, 450, 600, ""); 
    ;print("Create Window OK")
    GuiSetState()
EndFunc
; ===================================================
Func GUI_close()
    GUIDelete($GUImodWindow)
    GUIDelete($GUImodList)
    _GDIPlus_GraphicsDispose( $graphic )
    _GDIPlus_BitmapDispose( $bitmap )
    _GDIPlus_GraphicsDispose( $buffer )
    _GDIPlus_ShutDown()
    Exit
EndFunc
; ===================================================
Func listViewItem_clicked()
    Local $i,$j
    Local $item = _GUICtrlListView_GetItem($listView, Number(_GUICtrlListView_GetSelectedIndices($listView)));
    $i = Number( $item[3] ); // Item text
    $j = $i
    ;_GuiCtrlMakeTrans($butAry[$i],255);
    if $lastClick <> -1 then
    ;    GUICtrlSetColor($butAry[$lastClick], 0x000000);
        ;DrawString( $modNameAry[$lastClick], NormalizeX(int($modX1Ary[$lastClick])), NormalizeY(int($modY1Ary[$lastClick])+int($modHeight[$lastClick])), NormalizeW(int($modWidth[$lastClick])), NormalizeH(int($modHeight[$lastClick])),0x0000ff, 0xff000000, $gFontSize, $buffer)
        DrawString( $lastClick, 0x0000ff, 0xff000000, $gFontSize, $buffer)
    endif
    ;GUICtrlSetColor($butAry[$i+1], 0xff0000);
    DrawString( $j ,0xff0000, 0xff0000, $gFontSize, $buffer)
    _GDIPlus_GraphicsDrawImageRect($graphic, $bitmap, 0, 0, $xres, $yres )
    $lastClick = $j
    ;msgbox(0,"lol",stringformat("idx=%d",$i));
    print(StringFormat("idx=%d name=%s (%s,%s) (%s,%s) width=%s height=%s",$i,$modNameAry[$i],$modX1Ary[$i],$modY1Ary[$i],$modX2Ary[$i],$modY2Ary[$i],$modWidth[$i],$modHeight[$i]))
EndFunc
; ===================================================
Func FindMaxMinXYAndTotalModules(  )
    ;Local $fp
    ;$fp = FileOpen( $fileName, 0 )
    ;if $fp == -1 Then
    ;    msgbox(0,"lol","Open file error")
    ;    return
    ;Endif
    $totModules = 0; 
    Local $flag = 0
    Local $tmpX1, $tmpY1, $tmpX2, $tmpY2
    ; Load modules and Find max min boundary
    ;while 1
    Local $i
    For $i = 0 to _GUICtrlEdit_GetLineCount($EDIT)-1
        ;Local $line = FileReadLine( $fp )
        Local $line = _GUICtrlEdit_GetLine($EDIT,$i)
        ;msgbox(0,"lol",string($line))
        if @error = -1 Then ExitLoop
        Local $strs = getVar( $line )
        
;_ArrayDisplay($strs,"221")
        ;switch _ArraySize($strs)
        switch $strs[0]
        ; 5 parameter 
        case 4
            Local $b_w,$b_h
            $tmpX1 = int($strs[1])
            $tmpY1 = int($strs[2])
            $tmpX2 = int($strs[3])
            $tmpY2 = int($strs[4])
            $b_w = int( $strs[3] )-int( $strs[1] );
            $b_h = int( $strs[4] )-int( $strs[2] );
            _ArrayAdd( $modNameAry, "block" )
            _ArrayAdd( $modX1Ary,   $strs[1] )
            _ArrayAdd( $modY1Ary,   $strs[2] )
            _ArrayAdd( $modX2Ary,   $strs[3] )
            _ArrayAdd( $modY2Ary,   $strs[4] )
            _ArrayAdd( $modWidth,   String($b_w) )
            _ArrayAdd( $modHeight,  String($b_h) )
            setBoundary( $tmpX1, $tmpY1, $tmpX2, $tmpY2 )
            
            $totModules = $totModules + 1
        case 5
;        ; Load modules
            Local $b_w,$b_h
            $tmpX1 = int($strs[2])
            $tmpY1 = int($strs[3])
            $tmpX2 = int($strs[4])
            $tmpY2 = int($strs[5])
            $b_w = int( $strs[4] )-int( $strs[2] );
            $b_h = int( $strs[5] )-int( $strs[3] );
            _ArrayAdd( $modNameAry, $strs[1] )
            _ArrayAdd( $modX1Ary,   $strs[2] )
            _ArrayAdd( $modY1Ary,   $strs[3] )
            _ArrayAdd( $modX2Ary,   $strs[4] )
            _ArrayAdd( $modY2Ary,   $strs[5] )
            _ArrayAdd( $modWidth,   String($b_w) )
            _ArrayAdd( $modHeight,  String($b_h) )
            setBoundary( $tmpX1, $tmpY1, $tmpX2, $tmpY2 )
            
            $totModules = $totModules + 1
        case Else
            ContinueLoop;
        EndSwitch
        ;print(stringformat("parse line:%d %s size=%d",$totModules, $line,_ArraySize($strs))) 
;        switch _ArraySize($strs)
;        case 3
;            ;print(stringformat("get %s %s",$strs[1], $strs[2]))
;            ;$flag = (( $flag + 1 ) % 7 );
;            $flag = mod( $flag + 1, 7 )
;            if $flag == 1 then
;                $tmpX1 = int($strs[1])
;                $tmpY1 = int($strs[2])
;                _ArrayAdd( $modX1Ary, $strs[1] )
;                _ArrayAdd( $modY1Ary, $strs[2] )
;            elseif $flag == 3 then
;                $tmpX2 = int($strs[1])
;                $tmpY2 = int($strs[2])
;                _ArrayAdd( $modX2Ary, $strs[1] )
;                _ArrayAdd( $modY2Ary, $strs[2] )
;                Local $b_w, $b_h
;                $b_w = int( $tmpX2 ) - int( $tmpX1 )
;                $b_h = int( $tmpY2 ) - int( $tmpY1 )
;                _ArrayAdd( $modWidth,   String($b_w) )
;                _ArrayAdd( $modHeight,  String($b_h) )
;                setBoundary( $tmpX1, $tmpY1, $tmpX2, $tmpY2 )
;            elseif $flag == 6 then
;                _ArrayAdd( $modP1XAry, $strs[1] )
;                _ArrayAdd( $modP1YAry, $strs[2] )
;            elseif $flag == 0 then
;                _ArrayAdd( $modP2XAry, $strs[1] )
;                _ArrayAdd( $modP2YAry, $strs[2] )
;            endif
;        case 4
;            ;print(stringformat("get %s %s %s",$strs[1], $strs[2], $strs[3]))
;            _ArrayAdd( $modNameAry, stringformat("%s_%d", $strs[2], $strs[3]) )
;        case Else
;            ContinueLoop;
;        EndSwityych
;    wend
    ; Extra boundary ( X:5% v.s. Y:5%, choose the smallest one )
    Next
    Local $detX = int(($MaxX-$MinX)/20)
    Local $detY = int(($MaxX-$MinX)/20)
    if $detX == 0 then
        $detX = 1
    endif
    if $detY == 0 then
        $detY = 1
    endif
    Local $extraBoundary = 0;
    if $detX > $detY then
        $extraBoundary = $detY
    else
        $extraBoundary = $detX
    endif
    $MinX = $MinX - $extraBoundary
    $MinY = $MinY - $extraBoundary
    $MaxX = $MaxX + $extraBoundary
    $MaxY = $MaxY + $extraBoundary
;        
;        if _ArraySize($strs) < 5 then
;            ContinueLoop; 
;        endif
;        
;        
;        ; Load modules
;        Local $b_w,$b_h
;        $b_w = int( $strs[4] )-int( $strs[2] );
;        $b_h = int( $strs[5] )-int( $strs[3] );
;        _ArrayAdd( $modNameAry, $strs[1] )
;        _ArrayAdd( $modX1Ary,   $strs[2] )
;        _ArrayAdd( $modY1Ary,   $strs[3] )
;        _ArrayAdd( $modX2Ary,   $strs[4] )
;        _ArrayAdd( $modY2Ary,   $strs[5] )
;        _ArrayAdd( $modWidth,   String($b_w) )
;        _ArrayAdd( $modHeight,  String($b_h) )
        ; Find min max boundary
    print(stringformat("minX=%d maxX=%d minY=%d maxY=%d\n", $minX, $maxX, $minY, $maxY));
    Local $width = ($maxX - $minX)
    Local $height = ($maxY - $minY)
    Local $ratio = $width/$height
    ;msgbox(0,"lol",stringformat("%f",$ratio)) 
    print(stringformat( "Total modules = %d", $totModules ));
    print(stringformat( "Boundary (%d, %d) (%d, %d) W=%d H=%d", $minX, $minY, $maxX, $maxY, $width, $height) );
    if $width <= 0 then
        $width = $xres
    endif
    
    if $height <= 0 then
        $height = $xres
    endif
    if $ratio > 1 then
        ;$xres = $xres
        $yres = $yres*(1.0/$ratio)
    else
        $xres = $xres*$ratio
        ;$yres = 600
    endif
 ;   FileClose($fp)
EndFunc
; ===================================================
Func FindMaxMinXYAndTotalModulesSP(  )
    $totModules = 0; 
    Local $flag = 0
    Local $tmpX1, $tmpY1, $tmpX2, $tmpY2
    ; Load modules and Find max min boundary
    Local $i
    For $i = 0 to _GUICtrlEdit_GetLineCount($EDIT)-1
        Local $line = _GUICtrlEdit_GetLine($EDIT,$i)
        if @error = -1 Then ExitLoop
        Local $strs = getVar( $line )
        switch $strs[0]
        ; 5 parameter 
        case 4
            Local $b_w,$b_h
            $tmpX1 = int($strs[1])
            $tmpY1 = int($strs[2])
            $tmpX2 = int($strs[3])
            $tmpY2 = int($strs[4])
            $b_w = int( $strs[3] )-int( $strs[1] );
            $b_h = int( $strs[4] )-int( $strs[2] );
            _ArrayAdd( $modNameAry, "block" )
            _ArrayAdd( $modX1Ary,   $strs[1] )
            _ArrayAdd( $modY1Ary,   $strs[2] )
            _ArrayAdd( $modX2Ary,   $strs[3] )
            _ArrayAdd( $modY2Ary,   $strs[4] )
            _ArrayAdd( $modWidth,   String($b_w) )
            _ArrayAdd( $modHeight,  String($b_h) )
            setBoundary( $tmpX1, $tmpY1, $tmpX2, $tmpY2 )
            
            $totModules = $totModules + 1
        case 5
;        ; Load modules
            Local $b_w,$b_h
            $tmpX1 = int($strs[2])
            $tmpY1 = int($strs[3])
            $tmpX2 = int($strs[4])
            $tmpY2 = int($strs[5])
            $b_w = int( $strs[4] )-int( $strs[2] );
            $b_h = int( $strs[5] )-int( $strs[3] );
            _ArrayAdd( $modNameAry, $strs[1] )
            _ArrayAdd( $modX1Ary,   $strs[2] )
            _ArrayAdd( $modY1Ary,   $strs[3] )
            _ArrayAdd( $modX2Ary,   $strs[4] )
            _ArrayAdd( $modY2Ary,   $strs[5] )
            _ArrayAdd( $modWidth,   String($b_w) )
            _ArrayAdd( $modHeight,  String($b_h) )
            setBoundary( $tmpX1, $tmpY1, $tmpX2, $tmpY2 )
            
            $totModules = $totModules + 1
        case Else
            ContinueLoop;
        EndSwitch
    Next
    Local $detX = int(($MaxX-$MinX)/20)
    Local $detY = int(($MaxX-$MinX)/20)
    if $detX == 0 then
        $detX = 1
    endif
    if $detY == 0 then
        $detY = 1
    endif
    Local $extraBoundary = 0;
    if $detX > $detY then
        $extraBoundary = $detY
    else
        $extraBoundary = $detX
    endif
    $MinX = $MinX - $extraBoundary
    $MinY = $MinY - $extraBoundary
    $MaxX = $MaxX + $extraBoundary
    $MaxY = $MaxY + $extraBoundary
        ; Find min max boundary
    print(stringformat("minX=%d maxX=%d minY=%d maxY=%d\n", $minX, $maxX, $minY, $maxY));
    Local $width = ($maxX - $minX)
    Local $height = ($maxY - $minY)
    Local $ratio = $width/$height
    print(stringformat( "Total modules = %d", $totModules ));
    print(stringformat( "Boundary (%d, %d) (%d, %d) W=%d H=%d", $minX, $minY, $maxX, $maxY, $width, $height) );
    if $width <= 0 then
        $width = $xres
    endif
    
    if $height <= 0 then
        $height = $xres
    endif
    if $ratio > 1 then
        $yres = $yres*(1.0/$ratio)
    else
        $xres = $xres*$ratio
    endif
EndFunc
; ===================================================
Func setBoundary( $x1, $y1, $x2, $y2 )

        if (int($x1) > $maxX )  then
            $maxX = int($x1)
        endif

        if( int($x1) < $minX ) then
            $minX = int($x1)
        endif
        
        if( int($x2) > $maxX ) then
            $maxX = int($x2)
        endif

        if( int($x2) < $minX ) then
            $minX = int($x2)
        endif
        
        if( int($y1) > $maxY ) then
            $maxY = int($y1)
        endif

        if( int($y1) < $minY ) then
            $minY = int($y1)
        endif
        
        if( int($y2) > $maxY ) then
            $maxY = int($y2)
        endif

        if( int($y2) < $minY ) then
            $minY = int($y2)
        endif
EndFunc        
; ===================================================
Func NormalizeW( $w )
    Local $val = (($w)/($maxX-$minX))
    if $val > 1 then
        msgbox(0,"lol","w > 1 error")
    endif
    ;return int(800*($x-$minX)/($maxX-$minX))
    return int( $xres *$val)
EndFunc
; ===================================================
Func NormalizeH( $h )
    Local $val = (($h)/($maxY-$minY))
    if $val > 1 then
        msgbox(0,"lol","w > 1 error")
    endif
    ;return int(800*($x-$minX)/($maxX-$minX))
    return int( $yres*$val)
EndFunc
; ===================================================
Func NormalizeX( $x )
    ;return $x
    Local $val = (($x-$minX)/($maxX-$minX))
    if $val > 1 then
        msgbox(0,"lol","x > 1 error")
    endif
    ;return int(800*($x-$minX)/($maxX-$minX))
    return int( $xres*$val)
EndFunc
; ===================================================
Func NormalizeY( $y )
    ;return $y
    Local $val = (($y-$minY)/($maxY-$minY))
    if $val > 1 then
        msgbox(0,"lol", "y > 1 error")
    endif
    ;return 600-int(600*($y-$minY)/($maxY-$minY))
    return $yres-int($yres*$val)
EndFunc
; ===================================================
Func getVar($line)
    Local $strs = stringSplit($line, " (,)[]{}")
    Local $retAry[1]
    Local $i
    Local $count=0
    For $i=1 to $strs[0]
        if $strs[$i] <> "" then
            _ArrayAdd($retAry, $strs[$i] )
            $count = $count + 1
        endif
    Next
    $retAry[0] = $count
    return $retAry
EndFunc
; ===================================================
Func getInts($line)
    Local $strs = stringSplit($line, "(,)")
    return $strs
EndFunc
; ===================================================
Func PAINT_FLUSH()
    

    Local $whitePen = _GDIPlus_BrushCreateSolid(0)
    _GDIPlus_BrushSetSolidColor( $whitePen, "0xFFFFFFFF" )
    _GDIPlus_GraphicsFillRect( $buffer, 0, 0, $xres, $yres, $whitePen )
    Local $myColor = 0xFF0000FF
    Local $i
    For $i=1 to $totModules
        DrawString( $i, $myColor, 0xff000000, $gFontSize, $buffer)
    Next
    _GDIPlus_GraphicsDrawImageRect($graphic, $bitmap, 0, 0, $xres, $yres )
    _GDIPlus_BrushDispose( $whitePen )
EndFunc
; ===================================================
Func LoadModules()
   

    $graphic = _GDIPlus_GraphicsCreateFromHWND( $GUImodWindow )
    if 0 == $graphic then
        print("Create Graphics failed")
    else
        print("Create Graphics succefully...")
    endif
    $bitmap = _GDIPlus_BitmapCreateFromGraphics( $xres, $yres, $graphic )
    if 0 == $bitmap then
        print("Create Bitmap failed")
    else
        print("Create Bitmap succefully...")
    endif
    $buffer = _GDIPlus_ImageGetGraphicsContext( $bitmap )
    if 0 == $buffer then
        print("Create Buffer failed")
    else
        print("Create Buffer succefully...")
    endif
    Local $i
    For $i=1 to $totModules
        print(stringformat("Add %d %s",$i,$modNameAry[$i]))
        
        ;if -1 == _ArrayAdd($butAry, create_button($modNameAry[$i], NormalizeX(int($modX1Ary[$i]))  , NormalizeY(int($modY1Ary[$i])) - NormalizeH(int($modHeight[$i])) , NormalizeW(int($modWidth[$i])), NormalizeH(int($modHeight[$i])),"")) then
        ;    printf(stringformat("Create button %s failed",$modNameAry[$i]))
        ;endif
        
        if -1 == _ArrayAdd($itemAry, create_listViewItem( $listView, $i, $modNameAry[$i], $modX1Ary[$i], $modY1Ary[$i], $modX2Ary[$i], $modY2Ary[$i], $modWidth[$i], $modHeight[$i], "listViewItem_clicked" )) then
            printf(stringformat("Insert ListViewItem %s failed",$modNameAry[$i]))
        endif
    Next
    PAINT_FLUSH()
EndFunc
; ==================================================
Func ResetValue()
    $verbose         = 1
    $lastClick       = -1
    $xres            = 750
    $yres            = 750
    $maxX            = -9999999
    $maxY            = -9999999
    $minX            =  9999999
    $minY            =  9999999
    $gFontSize       = 10
    ;$FileList        = 0
    ;$ModulePath      = 0
    ; ====== GDIP relative variables ======
    if $graphic <> 0 then
        _GDIPlus_GraphicsDispose( $graphic )
    endif
    if $bitmap <> 0 then
        _GDIPlus_BitmapDispose( $bitmap )
    endif
    if $buffer <> 0 then
        _GDIPlus_GraphicsDispose( $buffer )
    endif
    $graphic         = 0
    $bitmap          = 0
    $buffer          = 0
    ; Array size will be size + 1, the first element is null since
    ; it cannot support zero size array :(
    ;$modNameAry[1];
    ;$modX1Ary[1], $modY1Ary[1], $modX2Ary[1], $modY2Ary[1]
    ;$modWidth[1], $modHeight[1];
    Local $i
    
    For $i=1 to $totModules
        _ArrayPop($modNameAry)
        _ArrayPop($modX1Ary)
        _ArrayPop($modY1Ary)
        _ArrayPop($modX2Ary)
        _ArrayPop($modY2Ary)
        _ArrayPop($modWidth)
        _ArrayPop($modHeight)
        _ArrayPop($modP1XAry)
        _ArrayPop($modP1YAry)
        _ArrayPop($modP2XAry)
        _ArrayPop($modP2YAry)
    Next
    $totModules      = 0
    ;;Global $butAry[1]
    ;$itemAry[1]
    ; Widgets
    ;$GUImodWindow    = 0;
    ;$GUImodList      = 0;
    ;$EDIT            = 0;
    ;Global $but_OK         = 0;
    ;$listView        = 0;
    ;$comboBox        = 0;
    _GUICtrlListView_DeleteAllItems($listView)
EndFunc
; ==================================================
Func SPCallback()
    ResetValue()

    FindMaxMinXYAndTotalModulesSP(  )

    create_window();
    LoadModules()
EndFunc
; ==================================================
Func comboBoxCallback()
    ResetValue()
	;Local $fileName = stringformat("%s/%s", $ModulePath, GUICtrlRead($comboBox) )
    ;msgbox(0,"lol",stringformat("%s/%s",$ModulePath,$temp_string))
    ;print(stringformat( "Oepn file %s", $fileName ))

    FindMaxMinXYAndTotalModules(  )

    create_window();
    ;print( stringformat( "Window size xres=%d yres=%d",$xres, $yres ) )
    LoadModules()
EndFunc
; ==================================================
; new flow
; createListWindow 
; click comboBox 
;   reset listView
;   update listView
;   create_window
; ===================================================
Func main()

    if true == _GDIPlus_StartUp() then
        print("_GDIPlus start successfully...")
    else
        print("_GDIPlus failed...")
    endif
    create_ListWindow();
    ;Local $fileName = FileOpenDialog("Please select a module file", @WorkingDir, "Text (*.txt)", 1 + 2)
    
    ; sleep 10 seconds to reduce CPU usage
    while 1
        sleep(100000);
    wend
    
    _GDIPlus_GraphicsDispose( $graphic )
    _GDIPlus_BitmapDispose( $bitmap )
    _GDIPlus_GraphicsDispose( $buffer )
    _GDIPlus_ShutDown()
    
EndFunc


; ===================================================
; Transparent object
; Ref http://www.autoitscript.com/forum/topic/73121-transparent-controls/page__p__533136#entry533136
; Author: ChrisL 08 June 2008
Func _GuiCtrlMakeTrans($iCtrlID,$iTrans=255)
    
    Local $pHwnd, $nHwnd, $aPos, $a
    Local $hWnd 
    $hWnd = GUICtrlGetHandle($iCtrlID);Get the control handle
    If $hWnd = 0 then Return SetError(1,1,0) 
    $pHwnd = DllCall("User32.dll", "hwnd", "GetParent", "hwnd", $hWnd);Get the parent Gui Handle
    If $pHwnd[0] = 0 then Return SetError(1,2,0)
    $aPos = ControlGetPos($pHwnd[0],"",$hWnd);Get the current pos of the control
    If @error then Return SetError(1,3,0)
    $nHwnd = GUICreate("", $aPos[2], $aPos[3], $aPos[0], $aPos[1], 0x80000000, 0x00080000 + 0x00000040, $pHwnd[0]);greate a gui in the position of the control
    If $nHwnd = 0 then Return SetError(1,4,0)
    $a = DllCall("User32.dll", "hwnd", "SetParent", "hwnd", $hWnd, "hwnd", $nHwnd);change the parent of the control to the new gui
    If $a[0] = 0 then Return SetError(1,5,0)
    If NOT ControlMove($nHwnd,'',$hWnd,0,0) then Return SetError(1,6,-1);Move the control to 0,0 of the newly created child gui
    GUISetState(@SW_Show,$nHwnd);show the new child gui
    WinSetTrans($nHwnd,"",$iTrans);set the transparency
    If @error then Return SetError(1,7,0)
    GUISwitch($pHwnd[0]);switch back to the parent Gui
    
    Return $nHwnd;Return the handle for the new Child gui
    
EndFunc


; ===================================================
;       GDIP drawing functions
; ===================================================
;Func DrawString( $str, $x, $y, $w, $h, $p1X, $p1Y, $p2X, $p2Y, $color, $bgColor, $fontSize, $buffer)
Func DrawString( $i, $color, $bgColor, $fontSize, $buffer)
    Local $str  =  $modNameAry[$i]
    Local $x    = NormalizeX(int($modX1Ary[$i])) 
    Local $y    = NormalizeY(int($modY1Ary[$i])+int($modHeight[$i])) 
    Local $w    = NormalizeW(int($modWidth[$i]))
    Local $h    = NormalizeH(int($modHeight[$i]))
    ;Local $p1X  = NormalizeX(int($modP1XAry[$i]))  
    ;Local $p1Y  = NormalizeY(int($modP1YAry[$i]))  
    ;Local $p2X  = NormalizeX(int($modP2XAry[$i]))  
    ;Local $p2Y  = NormalizeY(int($modP2YAry[$i]))  


    $color = BitOR( 0xFF000000, $color )
    Local $Pen = _GDIPlus_BrushCreateSolid(0)
    Local $Brush = _GDIPlus_BrushCreateSolid( $color )
    ;Local $color1 = 0x1000FF00;
    Local $rr = random( 1, 255, 1);
    Local $gg = random( 1, 255, 1);
    Local $bb = random( 1, 255, 1);
    Local $color1 = $rr * 65536 + $gg * 256 + $bb;
    $color1 = BitOR( 0x20000000, $color1 )
    Local $Brush1 = _GDIPlus_BrushCreateSolid( $color1 )
    Local $Format = _GDIPlus_StringFormatCreate()
    Local $Family = _GDIPlus_FontFamilyCreate("Courier New")
    ;Local $Family = _GDIPlus_FontFamilyCreate("Arial")
    Local $Font = _GDIPlus_FontCreate( $Family, $fontSize, 1 )
    Local $Rect[2][4]
    $rect[0][0] = 1;
    $Rect[1][0] = $x
    $Rect[1][1] = $y
    $Rect[1][2] = $w
    $Rect[1][3] = $h
    Local $strlen = StringLen( $str )
    Local $Layout = _GDIPlus_RectFCreate( $x+($w-$strlen*$gFontSize)/2, $y+($h-$gFontSize)/2, 0, 0 )
    Local $Info = _GDIPlus_GraphicsMeasureString( $buffer, $str, $Font, $Layout, $Format)

    $bgColor = BitOR( 0xFF000000, $bgColor )
    ; Pen, buffer
    _GDIPlus_BrushSetSolidColor( $Pen, $bgColor )
    ;_GDIPlus_GraphicsFillRect( $buffer, $x, $y, $w, $h, $Pen )

	Local $hPen = _GDIPlus_PenCreate($bgcolor, 1)
    _GDIPlus_GraphicsFillRectangles($buffer, $Rect, $Brush1)
    _GDIPlus_GraphicsDrawRectangles($buffer, $Rect, $hPen)

   ; Local $Point[3][2]
   ; $Point[0][0] = 2;
   ; $Point[1][0] = $p1X
   ; $Point[1][1] = $p1Y
   ; $Point[2][0] = $p2X
   ; $Point[2][1] = $p2Y
   ; _GDIPlus_GraphicsDrawLines($buffer, $Point, $hPen )

	_GDIPlus_PenDispose($hPen)

    _GDIPlus_GraphicsDrawStringEx( $buffer, $str, $Font, $Info[0], $Format, $Brush )

    ; Clean up resources
    _GDIPlus_BrushDispose( $Pen )
    _GDIPlus_BrushDispose( $Brush )
    _GDIPlus_StringFormatDispose ( $Format )
    _GDIPlus_FontFamilyDispose( $Family )
    _GDIPlus_FontDispose( $Font )
EndFunc
Func SavePath( $path )
    Local $configFile

    $configFile = FileOpen( ".myPath", 2 )
    if $configFile = -1 then
        Msgbox(0,"Error", "Unable to open file .myPath")
        return;
    endif
    FileWrite($configFile, string($path) )
    FileClose( $configFile )
EndFunc
; ===================================================
Func LoadPath()
    Local $fp
    Local $ret
    $fp = FileOpen( ".myPath", 0 )
    if $fp = -1 then
        ;Msgbox(0,"Error", "Unable to open file .myPath")
        return "";
    endif
    
    Local $line = FileReadLine( $fp )
    Local $strs = getVar( $line )
         
    if _ArraySize($strs) < 1 then
        $ret=""
    else
        $ret=$strs[1]
    endif

    FileClose( $fp )
    return $ret
EndFunc
; ===================================================
Func SetComboBox($combo, $FileList )
    Local $i

    For $i=1 to int($FileList[0])
        GuiCtrlSetData( $combo, string($FileList[$i] ) ); login, lk, senv
    Next
EndFunc
; ===================================================
;       main ( Code Entry )
; ===================================================
; Get path from path file, default is working directory
;Local $dir = LoadPath()
;if $dir == "" then
;    $dir = @WorkingDir
;endif
;
;$ModulePath = FileSelectFolder( "Please select a solution folder",@HomeDrive,-1, $dir )
;if $ModulePath <> "" then
;    ; save to config
;    SavePath( $ModulePath )
;endif
;$FileList = _FileListToArray( $ModulePath )
;_ArrayDisplay($FileList,"$FileList")

main()
; ===================================================
